package com.ibm.iisp.common.log;

import java.net.URL;
import java.util.Map;

import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;

/**
 *
 * @author Johnny@cn.ibm.com
 *
 */
public class LogbackConfigurer {

	/**
	 * @param location
	 *            log config file home path
	 * @param props
	 *            config properties
	 */
	public LogbackConfigurer(String location, Map<String, String> props) {
		super();
		this.setSystemProperties(props);
		initLogging(location);
	}

	/** Pseudo URL prefix for loading from the class path: "classpath:" */
	public static final String CLASSPATH_URL_PREFIX = "classpath:";

	/** Extension that indicates a logback XML config file: ".xml" */
	public static final String XML_FILE_EXTENSION = ".xml";

	private static LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
	private static JoranConfigurator configurator = new JoranConfigurator();

	/**
	 * Initialize logback from the given file location, with no config file
	 * refreshing. Assumes an XML file in case of a ".xml" file extension, and a
	 * properties file otherwise.
	 *
	 * @param location
	 *            the location of the config file: either a "classpath:"
	 *            location (e.g. "classpath:mylogback.properties"), an absolute
	 *            file URL (e.g.
	 *            "file:C:/logback.properties), or a plain absolute path in the file system (e.g. "
	 *            C:/logback.properties")
	 */
	public void initLogging(String location) {
		String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);

		try {
			URL url = ResourceUtils.getURL(resolvedLocation);
			if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
				configurator.setContext(lc);
				lc.reset();
				configurator.doConfigure(url);
				lc.start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Shut down logback, properly releasing all file locks.
	 * <p>
	 * This isn't strictly necessary, but recommended for shutting down logback
	 * in a scenario where the host VM stays alive (for example, when shutting
	 * down an application in a J2EE environment).
	 */
	public void shutdown() {
		lc.stop();
	}

	/**
	 * Set the specified system property to the current working directory.
	 * <p>
	 * This can be used e.g. for test environments, for applications that
	 * leverage logbackWebConfigurer's "webAppRootKey" support in a web
	 * environment.
	 *
	 * @param key
	 *            system property key to use, as expected in logback
	 *            configuration (for example: "demo.root", used as
	 *            "${demo.root}/WEB-INF/demo.log")
	 * @see org.springframework.web.util.logbackWebConfigurer
	 */
	void setSystemProperties(Map<String, String> props) {
		for (Map.Entry<String, String> entry : props.entrySet()) {
			System.setProperty(entry.getKey(), entry.getValue());
		}
	}

}
